package com.ruoyi.fun.controller;

import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.system.domain.SysUserWechat;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.system.service.ISysUserWechatService;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.framework.web.service.SysLoginService;
import com.ruoyi.framework.web.service.SysPermissionService;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.PasswordEncryptionUtils;
import com.ruoyi.fun.service.ISysWechatConfigService;
import com.ruoyi.fun.domain.SysWechatConfig;
import java.util.Set;
import java.util.HashSet;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;
import java.util.HashMap;
import java.util.Date;
import java.util.Random;

/**
 * 微信登录Controller
 * 
 * @author ruoyi
 * @date 2025-01-15
 */
@Anonymous
@RestController
@RequestMapping("/mobile/wechat")
public class WechatLoginController extends BaseController {
    
    // 微信小程序配置信息已移至前端配置，通过接口参数传递
    
    @Autowired
    private ISysUserWechatService sysUserWechatService;
    
    @Autowired
    private ISysUserService userService;
    
    @Autowired
    private TokenService tokenService;
    
    @Autowired
    private SysLoginService loginService;
    
    @Autowired
    private PasswordEncryptionUtils passwordEncryptionUtils;
    
    @Autowired
    private SysPermissionService permissionService;

    @Value("${password.encryption.key}")
    private String encryptionKey;

    @Autowired
    private ISysWechatConfigService sysWechatConfigService;
    

    
    /**
     * 微信登录 - 通过code获取openid
     */
    @Log(title = "微信登录", businessType = BusinessType.OTHER)
    @PostMapping("/login")
    public AjaxResult wechatLogin(@RequestBody Map<String, String> params) {
        try {
            String code = params.get("code");
            if (code == null || code.trim().isEmpty()) {
                return AjaxResult.error("登录凭证code不能为空");
            }
            // 基于 orgId + appId 动态获取 AppSecret
            String orgId = resolveOrgId(params);
            String appId = params.get("appId");

            if (appId == null || appId.trim().isEmpty()) {
                return AjaxResult.error("微信APPID不能为空");
            }
            if (orgId == null || orgId.trim().isEmpty()) {
                return AjaxResult.error("组织ID不能为空");
            }

            SysWechatConfig config = sysWechatConfigService.selectByOrgIdAndAppId(orgId, appId);
            if (config == null) {
                return AjaxResult.error("未找到该组织与AppId对应的微信配置");
            }
            String appSecret = config.getWechatAppsecret();
            if (appSecret == null || appSecret.trim().isEmpty()) {
                return AjaxResult.error("系统未配置微信AppSecret，请在系统配置库中为该组织与AppId设置AppSecret");
            }

            // 调用微信接口获取openid
            Map<String, Object> wechatResult = callWechatCodeToSessionWithParams(code, appId, appSecret);
            
            if (wechatResult.containsKey("errcode")) {
                return AjaxResult.error("微信登录失败: " + wechatResult.get("errmsg"));
            }
            
            String openid = (String) wechatResult.get("openid");
            String sessionKey = (String) wechatResult.get("session_key");
            String unionid = (String) wechatResult.get("unionid");
            
            // 构建返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("openid", openid);
            result.put("sessionKey", sessionKey);
            result.put("unionid", unionid);
            result.put("loginTime", System.currentTimeMillis());
            
            // 这里可以添加用户信息查询和创建逻辑
            // 例如：根据openid查询用户是否存在，不存在则创建新用户
            
            return AjaxResult.success("微信登录成功", result);
            
        } catch (Exception e) {
            logger.error("微信登录异常", e);
            return AjaxResult.error("微信登录失败: " + e.getMessage());
        }
    }
    
    /**
     * 调用微信code2Session接口（已废弃，请使用callWechatCodeToSessionWithParams）
     */
    @Deprecated
    private Map<String, Object> callWechatCodeToSession(String code) throws Exception {
        throw new UnsupportedOperationException("请使用callWechatCodeToSessionWithParams方法，并传入appId和appSecret参数");
    }
    
    /**
     * 调用微信code2Session接口（支持自定义参数）
     */
    private Map<String, Object> callWechatCodeToSessionWithParams(String code, String appId, String appSecret) throws Exception {
        String url = "https://api.weixin.qq.com/sns/jscode2session" +
                "?appid=" + appId +
                "&secret=" + appSecret +
                "&js_code=" + code +
                "&grant_type=authorization_code";
        
        logger.info("调用微信接口URL: {}", url.replaceAll("secret=[^&]*", "secret=***"));
        logger.info("使用的code: {}", code);
        
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
        
        logger.info("微信接口响应: {}", response.getBody());
        
        ObjectMapper objectMapper = new ObjectMapper();
         return objectMapper.readValue(response.getBody(), Map.class);
    }
    
    /**
     * 通过code获取OpenID
     */
    @Log(title = "获取OpenID", businessType = BusinessType.OTHER)
    @PostMapping("/getOpenId")
    public AjaxResult getOpenId(@RequestBody Map<String, String> params) {
        try {
            String code = params.get("code");
            String appId = params.get("appId");
            // 优先从系统配置库按 orgId + appId 获取 appSecret
            String orgId = resolveOrgId(params);
            
            if (code == null || code.trim().isEmpty()) {
                return AjaxResult.error("登录凭证code不能为空");
            }
            
            if (appId == null || appId.trim().isEmpty()) {
                return AjaxResult.error("微信APPID不能为空");
            }
            if (orgId == null || orgId.trim().isEmpty()) {
                return AjaxResult.error("组织ID不能为空");
            }

            // 若前端未传 appSecret，则从数据库动态加载
            String appSecret = params.get("appSecret");
            if (appSecret == null || appSecret.trim().isEmpty()) {
                SysWechatConfig config = sysWechatConfigService.selectByOrgIdAndAppId(orgId, appId);
                if (config == null) {
                    return AjaxResult.error("未找到该组织与AppId对应的微信配置");
                }
                appSecret = config.getWechatAppsecret();
                if (appSecret == null || appSecret.trim().isEmpty()) {
                    return AjaxResult.error("系统未配置微信AppSecret，请在系统配置库中为该组织与AppId设置AppSecret");
                }
            }
            
            // 调用微信接口获取openid
            Map<String, Object> wechatResult = callWechatCodeToSessionWithParams(code, appId, appSecret);
            
            if (wechatResult.containsKey("errcode")) {
                return AjaxResult.error("获取OpenID失败: " + wechatResult.get("errmsg"));
            }
            
            String openid = (String) wechatResult.get("openid");
            String sessionKey = (String) wechatResult.get("session_key");
            String unionid = (String) wechatResult.get("unionid");
            
            // 构建返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("openid", openid);
            result.put("sessionKey", sessionKey);
            result.put("unionid", unionid);
            result.put("timestamp", System.currentTimeMillis());
            
            return AjaxResult.success("获取OpenID成功", result);
            
        } catch (Exception e) {
            logger.error("获取OpenID异常", e);
            return AjaxResult.error("获取OpenID失败: " + e.getMessage());
        }
    }

    /**
     * 从参数中解析组织ID（兼容 orgId 与 deptId）
     */
    private String resolveOrgId(Map<String, String> params) {
        String orgId = params.get("orgId");
        if (orgId == null || orgId.trim().isEmpty()) {
            orgId = params.get("deptId");
        }
        return orgId;
    }
    
    /**
     * 获取微信配置信息（用于前端调试）
     */
    @GetMapping("/config")
    public AjaxResult getWechatConfig() {
        Map<String, Object> config = new HashMap<>();
        config.put("message", "微信配置信息已移至前端管理");
        config.put("note", "请在前端config.js中配置WECHAT_APPID和WECHAT_APPSECRET");
        return AjaxResult.success(config);
    }
    
    /**
     * 根据OpenID查询用户微信绑定信息
     */
    @Log(title = "查询微信绑定信息", businessType = BusinessType.OTHER)
    @GetMapping("/getUserByOpenId")
    public AjaxResult getUserByOpenId(@RequestParam("openId") String openId) {
        try {
            if (openId == null || openId.trim().isEmpty()) {
                return AjaxResult.error("OpenID不能为空");
            }
            
            // 根据OpenID查询微信绑定信息
            SysUserWechat userWechat = sysUserWechatService.selectSysUserWechatByOpenId(openId);
            
            if (userWechat == null) {
                return AjaxResult.error("未找到对应的微信绑定信息");
            }
            
            return AjaxResult.success("查询成功", userWechat);
            
        } catch (Exception e) {
            logger.error("查询微信绑定信息异常", e);
            return AjaxResult.error("查询失败: " + e.getMessage());
        }
    }
    
    /**
     * 根据用户ID查询用户信息
     */
    @Log(title = "查询用户信息", businessType = BusinessType.OTHER)
    @GetMapping("/getUserById")
    public AjaxResult getUserById(@RequestParam("userId") Long userId) {
        try {
            if (userId == null) {
                return AjaxResult.error("用户ID不能为空");
            }
            
            // 根据用户ID查询用户信息
            SysUser user = userService.selectUserById(userId);
            
            if (user == null) {
                return AjaxResult.error("未找到对应的用户信息");
            }
            
            return AjaxResult.success("查询成功", user);
            
        } catch (Exception e) {
            logger.error("查询用户信息异常", e);
            return AjaxResult.error("查询失败: " + e.getMessage());
        }
    }
    
    /**
     * 测试接口连通性
     */
    @GetMapping("/test")
    public AjaxResult test() {
        Map<String, Object> result = new HashMap<>();
        result.put("message", "微信登录接口连通正常");
        result.put("timestamp", System.currentTimeMillis());
        result.put("note", "微信配置信息请通过前端传递");
        return AjaxResult.success(result);
    }
    
    /**
     * 根据OpenID查询用户绑定信息
     */
    @Log(title = "查询用户绑定", businessType = BusinessType.OTHER)
    @PostMapping("/checkUser")
    public AjaxResult checkUserByOpenId(@RequestBody Map<String, String> params) {
        try {
            String openId = params.get("openId");
            if (openId == null || openId.trim().isEmpty()) {
                return AjaxResult.error("OpenID不能为空");
            }
            
            // 查询用户微信绑定信息
            SysUserWechat userWechat = sysUserWechatService.selectSysUserWechatByOpenId(openId);
            
            if (userWechat != null) {
                // 用户已绑定，返回用户信息
                SysUser user = userService.selectUserById(userWechat.getUserId());
                if (user != null && "0".equals(user.getStatus())) {
                    Map<String, Object> result = new HashMap<>();
                    result.put("userExists", true);
                    result.put("userId", user.getUserId());
                    result.put("userName", user.getUserName());
                    result.put("nickName", user.getNickName());
                    result.put("avatar", user.getAvatar());
                    return AjaxResult.success("用户已绑定", result);
                } else {
                    return AjaxResult.error("用户状态异常");
                }
            } else {
                // 用户未绑定
                Map<String, Object> result = new HashMap<>();
                result.put("userExists", false);
                return AjaxResult.success("用户未绑定，需要注册", result);
            }
            
        } catch (Exception e) {
            logger.error("查询用户绑定信息异常", e);
            return AjaxResult.error("查询用户绑定信息失败: " + e.getMessage());
        }
    }
    
    /**
     * 微信用户注册
     */
    @Log(title = "微信用户注册", businessType = BusinessType.INSERT)
    @PostMapping("/register")
    public AjaxResult registerWechatUser(@RequestBody Map<String, String> params) {
        try {
            String openId = params.get("openId");
            String nickName = params.get("nickName");
            String avatar = params.get("avatar");
            String orgId = params.get("deptId"); // 从前端获取组织ID
            
            if (openId == null || openId.trim().isEmpty()) {
                return AjaxResult.error("OpenID不能为空");
            }
            if (nickName == null || nickName.trim().isEmpty()) {
                return AjaxResult.error("用户昵称不能为空");
            }
            if (orgId == null || orgId.trim().isEmpty()) {
                return AjaxResult.error("组织ID不能为空");
            }
            
            // 检查用户是否已存在
            SysUserWechat existingUserWechat = sysUserWechatService.selectSysUserWechatByOpenId(openId);
            if (existingUserWechat != null) {
                return AjaxResult.error("用户已存在，无需重复注册");
            }
            
            // 生成随机用户名
            String userName = generateRandomUserName();
            
            // 生成10位随机密码
            String randomPassword = generateRandomPassword(10);
            
            // 加密密码
            String encryptedPassword = passwordEncryptionUtils.encrypt(randomPassword);
            
            // 创建新用户
            SysUser newUser = new SysUser();
            newUser.setUserName(userName);
            newUser.setNickName(nickName);
            newUser.setAvatar(avatar != null ? avatar : "");
            newUser.setPassword(encryptedPassword); // 使用加密后的随机密码
            newUser.setStatus("0"); // 正常状态
            newUser.setDeptId(Long.parseLong(orgId)); // 使用前端传递的组织ID
            newUser.setCreateBy("system");
            newUser.setCreateTime(DateUtils.getNowDate());
            
            // 插入用户
            int userResult = userService.insertUser(newUser);
            if (userResult <= 0) {
                return AjaxResult.error("用户注册失败");
            }
            
            // 设置用户角色（普通角色ID为2）
            Long[] roleIds = {2L};
            userService.insertUserAuth(newUser.getUserId(), roleIds);
            
            // 创建微信绑定记录
            SysUserWechat userWechat = new SysUserWechat();
            userWechat.setUserId(newUser.getUserId());
            userWechat.setOpenId(openId);
            userWechat.setPassword(encryptedPassword); // 存储加密后的密码
            userWechat.setBindTime(DateUtils.getNowDate());
            userWechat.setLastLoginTime(DateUtils.getNowDate());
            userWechat.setStatus("0");
            userWechat.setSelectedOrg(Long.parseLong(orgId)); // 使用前端传递的组织ID
            userWechat.setCreateBy("system");
            userWechat.setCreateTime(DateUtils.getNowDate());
            
            int wechatResult = sysUserWechatService.insertSysUserWechat(userWechat);
            if (wechatResult <= 0) {
                return AjaxResult.error("微信绑定失败");
            }
            
            // 创建LoginUser对象并生成JWT token
            LoginUser loginUser = new LoginUser();
            loginUser.setUserId(newUser.getUserId());
            loginUser.setDeptId(newUser.getDeptId());
            loginUser.setUser(newUser);
            String token = tokenService.createToken(loginUser);
            
            // 构建返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("userId", newUser.getUserId());
            result.put("userName", newUser.getUserName());
            result.put("nickName", newUser.getNickName());
            result.put("avatar", newUser.getAvatar());
            result.put("openId", openId);
            result.put("token", token);
            result.put("password", randomPassword); // 返回生成的随机密码供测试使用
            
            return AjaxResult.success("注册成功", result);
            
        } catch (Exception e) {
            logger.error("微信用户注册异常", e);
            return AjaxResult.error("注册失败: " + e.getMessage());
        }
    }
    
    /**
     * 微信自动登录
     */
    @Log(title = "微信自动登录", businessType = BusinessType.OTHER)
    @PostMapping("/autoLogin")
    public AjaxResult wechatAutoLogin(@RequestBody Map<String, String> params) {
        try {
            String openId = params.get("openId");
            String orgId = params.get("deptId"); // 从前端获取组织ID
            System.out.println("=== 微信自动登录开始 ===");
            System.out.println("接收到的OpenID: " + openId);
            System.out.println("接收到的组织ID: " + orgId);
            
            if (openId == null || openId.trim().isEmpty()) {
                System.out.println("OpenID为空，登录失败");
                return AjaxResult.error("OpenID不能为空");
            }
            
            // 如果没有传递组织ID，使用默认值
            if (orgId == null || orgId.trim().isEmpty()) {
                orgId = "114"; // 默认组织ID
                System.out.println("未传递组织ID，使用默认值: " + orgId);
            }
            
            // 查询用户微信绑定信息
            SysUserWechat userWechat = sysUserWechatService.selectSysUserWechatByOpenId(openId);
            System.out.println("查询到的微信绑定信息: " + (userWechat != null ? userWechat.toString() : "null"));
            
            if (userWechat != null) {
                System.out.println("找到绑定用户，用户ID: " + userWechat.getUserId());
                
                // 获取用户信息
                SysUser user = userService.selectUserById(userWechat.getUserId());
                System.out.println("查询到的用户信息: " + (user != null ? "用户名=" + user.getUserName() + ", 状态=" + user.getStatus() : "null"));
                
                if (user != null && "0".equals(user.getStatus())) {
                    System.out.println("用户状态正常，开始登录流程");
                    
                    // 更新最后登录时间
                    userWechat.setLastLoginTime(DateUtils.getNowDate());
                    sysUserWechatService.updateSysUserWechat(userWechat);
                    
                    // 从数据库获取加密密码并解密
                    String encryptedPassword = userWechat.getPassword();
                    System.out.println("从数据库获取的加密密码: " + encryptedPassword);
                    
                    String token = null;
                    if (encryptedPassword != null && !encryptedPassword.isEmpty()) {
                        try {
                            // 解密密码验证
                            String decryptedPassword = passwordEncryptionUtils.decrypt(encryptedPassword);
                            System.out.println("解密后的密码: " + decryptedPassword);
                            System.out.println("密码解密成功，直接为微信用户生成token");
                            
                            // 直接为微信用户创建LoginUser和token，绕过通用登录接口
                            LoginUser loginUser = new LoginUser();
                            loginUser.setUserId(user.getUserId());
                            loginUser.setDeptId(user.getDeptId());
                            loginUser.setUser(user);
                            
                            // 设置用户权限
                            Set<String> permissions = permissionService.getMenuPermission(user);
                            // 确保权限不为null，如果为null则设置为空集合
                            if (permissions == null) {
                                permissions = new HashSet<>();
                            }
                            loginUser.setPermissions(permissions);
                            
                            token = tokenService.createToken(loginUser);
                            System.out.println("微信用户token生成成功: " + token);
                        } catch (Exception e) {
                            System.out.println("密码解密失败: " + e.getMessage());
                            return AjaxResult.error("密码解密失败: " + e.getMessage());
                        }
                    } else {
                        System.out.println("数据库中未找到加密密码，无法进行微信登录");
                        return AjaxResult.error("用户密码信息异常，请重新注册");
                    }
                    
                    // 构建返回结果
                    Map<String, Object> result = new HashMap<>();
                    result.put("userId", user.getUserId());
                    result.put("userName", user.getUserName());
                    result.put("nickName", user.getNickName());
                    result.put("avatar", user.getAvatar());
                    result.put("token", token);
                    
                    System.out.println("=== 微信自动登录成功 ===");
                    return AjaxResult.success("自动登录成功", result);
                } else {
                    System.out.println("用户状态异常或用户不存在");
                    return AjaxResult.error("用户状态异常");
                }
            } else {
                System.out.println("未找到该OpenID对应的绑定用户，开始自动注册流程");
                
                // 自动注册新用户
                try {
                    // 生成随机用户名和昵称
                    String userName = generateRandomUserName();
                    String nickName = "微信用户" + System.currentTimeMillis();
                    
                    // 生成10位随机密码
                    String randomPassword = generateRandomPassword(10);
                    
                    // 加密密码
                    String encryptedPassword = passwordEncryptionUtils.encrypt(randomPassword);
                    
                    // 创建新用户
                    SysUser newUser = new SysUser();
                    newUser.setUserName(userName);
                    newUser.setNickName(nickName);
                    newUser.setAvatar(""); // 默认头像为空
                    newUser.setPassword(encryptedPassword); // 使用加密后的随机密码
                    newUser.setStatus("0"); // 正常状态
                    newUser.setDeptId(Long.parseLong(orgId)); // 使用动态获取的组织ID
                    newUser.setCreateBy("system");
                    newUser.setCreateTime(DateUtils.getNowDate());
                    
                    // 插入用户
                    int userResult = userService.insertUser(newUser);
                    if (userResult <= 0) {
                        System.out.println("自动注册用户失败");
                        return AjaxResult.error("自动注册失败");
                    }
                    
                    // 设置用户角色（普通角色ID为2）
                    Long[] roleIds = {2L};
                    userService.insertUserAuth(newUser.getUserId(), roleIds);
                    
                    // 创建微信绑定记录
                    SysUserWechat newUserWechat = new SysUserWechat();
                    newUserWechat.setUserId(newUser.getUserId());
                    newUserWechat.setOpenId(openId);
                    newUserWechat.setPassword(encryptedPassword); // 存储加密后的密码
                    newUserWechat.setBindTime(DateUtils.getNowDate());
                    newUserWechat.setLastLoginTime(DateUtils.getNowDate());
                    newUserWechat.setStatus("0");
                    newUserWechat.setSelectedOrg(Long.parseLong(orgId)); // 使用动态获取的组织ID
                    newUserWechat.setCreateBy("system");
                    newUserWechat.setCreateTime(DateUtils.getNowDate());
                    
                    int wechatResult = sysUserWechatService.insertSysUserWechat(newUserWechat);
                    if (wechatResult <= 0) {
                        System.out.println("自动创建微信绑定失败");
                        return AjaxResult.error("微信绑定失败");
                    }
                    
                    // 创建LoginUser对象并生成JWT token
                    LoginUser loginUser = new LoginUser();
                    loginUser.setUserId(newUser.getUserId());
                    loginUser.setDeptId(newUser.getDeptId());
                    loginUser.setUser(newUser);
                    
                    // 设置用户权限
                    Set<String> permissions = permissionService.getMenuPermission(newUser);
                    if (permissions == null) {
                        permissions = new HashSet<>();
                    }
                    loginUser.setPermissions(permissions);
                    
                    String token = tokenService.createToken(loginUser);
                    
                    // 构建返回结果
                    Map<String, Object> result = new HashMap<>();
                    result.put("userId", newUser.getUserId());
                    result.put("userName", newUser.getUserName());
                    result.put("nickName", newUser.getNickName());
                    result.put("avatar", newUser.getAvatar());
                    result.put("token", token);
                    result.put("isNewUser", true); // 标识这是新注册的用户
                    
                    System.out.println("=== 微信用户自动注册并登录成功 ===");
                    return AjaxResult.success("自动注册并登录成功", result);
                    
                } catch (Exception autoRegisterException) {
                    System.out.println("自动注册异常: " + autoRegisterException.getMessage());
                    logger.error("微信用户自动注册异常", autoRegisterException);
                    return AjaxResult.error("自动注册失败: " + autoRegisterException.getMessage());
                }
            }
            
        } catch (Exception e) {
            System.out.println("微信自动登录异常: " + e.getMessage());
            logger.error("微信自动登录异常", e);
            return AjaxResult.error("自动登录失败: " + e.getMessage());
        }
    }
    
    /**
     * 生成随机用户名
     */
    private String generateRandomUserName() {
        String chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        Random random = new Random();
        StringBuilder sb = new StringBuilder("user_");
        
        for (int i = 0; i < 10; i++) {
            sb.append(chars.charAt(random.nextInt(chars.length())));
        }
        
        return sb.toString();
    }
    
    /**
     * 生成随机密码
     */
    private String generateRandomPassword(int length) {
        String chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        Random random = new Random();
        StringBuilder sb = new StringBuilder();
        
        for (int i = 0; i < length; i++) {
            sb.append(chars.charAt(random.nextInt(chars.length())));
        }
        
        return sb.toString();
    }
}
